#include "downloadmodel.h"
#include "downloadmanager.h"

#include <QString>
#include <QFileInfo>
#include <QDebug>
#include <QSqlQuery>

DownloadModel::DownloadModel(QObject* parent)
    : QSqlTableModel(parent)
    , mgr_(new DownloadManager)
{
    statusMap[0] = "New task";
    statusMap[1] = "Running";
    statusMap[2] = "Completed";
    statusMap[3] = "Failed";

    setTable("downloads");
    setEditStrategy(QSqlTableModel::OnManualSubmit);

    setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
    setHeaderData(1, Qt::Horizontal, QObject::tr("File Name"));
    setHeaderData(2, Qt::Horizontal, QObject::tr("Path"));
    setHeaderData(3, Qt::Horizontal, QObject::tr("Size"));
    setHeaderData(4, Qt::Horizontal, QObject::tr("Downloaded"));
    setHeaderData(5, Qt::Horizontal, QObject::tr("Priority"));
    setHeaderData(6, Qt::Horizontal, QObject::tr("Status"));

    select();

    takeCareOfOldDownloads();
}

DownloadModel::~DownloadModel()
{
    submitAll();
}

QVariant DownloadModel::data(const QModelIndex &index, int role) const
{
    if (role == Qt::DisplayRole) {
        // Converting URL to file name
        if(index.column() == 1) {
            QString url = QSqlTableModel::data(index, role).toString();
            QFileInfo info(url);
            return info.fileName();
        }

        if(index.column() == 6) {
            int status = QSqlTableModel::data(index, role).toInt();
            return statusMap[status];
        }
    }
    return QSqlTableModel::data(index, role);
}

void DownloadModel::enqueueNewTask(TaskRecord* record)
{
    insertRecord(-1, record->getRecord());
    submitAll();

    int newid = query().lastInsertId().toInt();
    record->setId(newid);
    connect(record, SIGNAL(taskUpdated(int,QSqlRecord*)), this, SLOT(updateTask(int,QSqlRecord*)));
    updateTask(newid, &record->getRecord());
    mgr_->append(record);
}

void DownloadModel::updateTask(int id, QSqlRecord* record)
{
    buildPrimaryToRow();
    setRecord(primaryToRow[id], *record);
    emit layoutChanged();
}

// Dirtiest thing in the world, why i just can't update record using primary key of my table?!
void DownloadModel::buildPrimaryToRow()
{
    for(int row = 0; row < rowCount(); ++row)
    {
        primaryToRow[index(row, 0).data(Qt::DisplayRole).toInt()] = row;
    }
}

void DownloadModel::takeCareOfOldDownloads() {
    for(int row = 0; row < rowCount(); ++row)
    {
        int status = index(row, 6).data(Qt::EditRole).toInt();
        qDebug() << "status is " << status;
        // If task is marked running or new
        if (status < 2) {
            int id = index(row, 0).data().toInt();
            TaskRecord* record = new TaskRecord(
                        index(row, 1).data(Qt::EditRole).toString(),
                        index(row, 2).data(Qt::EditRole).toString(),
                        index(row, 5).data(Qt::EditRole).toInt(),
                        this);
            record->setId(id);
            connect(record, SIGNAL(taskUpdated(int,QSqlRecord*)), this, SLOT(updateTask(int,QSqlRecord*)));
            if (status == 1) {
                record->resetStatus();
                updateTask(id, &record->getRecord());
            }
            mgr_->append(record);
        }
    }
    submitAll();
}
